package com.lixy.office;

import org.apache.commons.io.FileUtils;
import org.apache.poi.hssf.usermodel.HSSFPrintSetup;
import org.apache.poi.ss.usermodel.PrintSetup;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.jodconverter.core.office.OfficeUtils;
import org.jodconverter.local.JodConverter;
import org.jodconverter.local.office.LocalOfficeManager;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.io.*;

/**
 * @author lishuai
 * @date 2021/09/29 13:51
 * @version: 1.0
 */
@Service
public class DynamicOffice2Pdf {

    @Value("${office.home.dir:/opt/openoffice4/}")
    private String OFFICE_HOME_DIR;

    @Value("${office.out.dir:/out/}")
    private String OFFICE_OUT_DIR;

    @Value("${office.convert.host:127.0.0.1}")
    private String HOST_NAME;

    /**
     * 文件转换到指定配置目录
     *
     * @param sourcePath
     * @return 生成pdf的文件路径
     */
    public String convert(String sourcePath) throws Exception {
        File file = new File(sourcePath);
        if (!file.exists()) {
            throw new RuntimeException("file not exists");
        }
        String name = file.getName();
        String newFileName = name.substring(0, name.lastIndexOf(".") + 1) + DocTypeEnum.PDF.getCode();
        return convert(file, OFFICE_OUT_DIR + newFileName);
    }

    /**
     * 文件转换到指定配置目录
     *
     * @param sourceFile
     */
    public String convert(File sourceFile) throws Exception {
        if (!sourceFile.exists()) {
            throw new RuntimeException("file not exists");
        }
        File outDir = new File(OFFICE_OUT_DIR);
        if (!outDir.exists() || !outDir.isDirectory()) {
            throw new RuntimeException("out dir not exists");
        }
        String name = sourceFile.getName();
        String newFileName = name.substring(0, name.lastIndexOf(".") + 1) + DocTypeEnum.PDF.getCode();
        return convert(sourceFile, OFFICE_OUT_DIR + newFileName);
    }

    /**
     * 文件流及文件名转换到生成文件
     *
     * @param in
     * @param fileName 文件名路径
     */
    public String convert(InputStream in, String fileName) throws Exception {
        if (in == null) {
            throw new RuntimeException("file not exists");
        }
        File outDir = new File(OFFICE_OUT_DIR);
        if (!outDir.exists() || !outDir.isDirectory()) {
            throw new RuntimeException("out dir not exists");
        }
        File file = new File(OFFICE_OUT_DIR + fileName);
        FileUtils.copyInputStreamToFile(in, file);
        String name = file.getName();
        String newFileName = name.substring(0, name.lastIndexOf(".") + 1) + DocTypeEnum.PDF.getCode();
        return convert(file, OFFICE_OUT_DIR + newFileName);
    }

    /**
     * 指定转换输出文件路径
     *
     * @param sourcePath  输入源文件路径
     * @param outFilePath 输入文件路径
     * @return
     * @throws Exception
     */
    public String convert(String sourcePath, String outFilePath) throws Exception {
        File file = new File(sourcePath);
        if (!file.exists()) {
            throw new RuntimeException("file not exists");
        }
        return convert(file, outFilePath);
    }

    /**
     * 文件转换
     *
     * @param sourceFile  输入源文件
     * @param outFilePath 输入文件路径
     * @return 生成pdf的文件路径
     */
    public String convert(File sourceFile, String outFilePath) throws Exception {
        if (!sourceFile.exists()) {
            throw new RuntimeException("file not exists");
        }

        File outDir = new File(OFFICE_OUT_DIR);
        if (!outDir.exists() || !outDir.isDirectory()) {
            throw new RuntimeException("out dir not exists");
        }
        File newFile = new File(outFilePath);
        LocalOfficeManager localOfficeManager = null;
        try {
       /* // 获取openoffice管理器
        LocalOfficeManager localOfficeManager = LocalOfficeManager.builder().officeHome(OFFICE_HOME_DIR).install().build();
        */
            LocalOfficeManager.Builder builder = LocalOfficeManager.builder();
            if (!StringUtils.isEmpty(HOST_NAME)) {
                builder.hostName(HOST_NAME);
            }
            localOfficeManager = builder.officeHome(OFFICE_HOME_DIR).install().build();
            // 判断openoffice服务是否打开
            if (!localOfficeManager.isRunning()) {
                localOfficeManager.start();
            }
            // 已开启预览设置，并且是xls文件
            if (sourceFile.getName().endsWith(DocTypeEnum.XLS.getCode()) || sourceFile.getName().endsWith(DocTypeEnum.XLSX.getCode())) {
                // 获取调整预览格式后的文件
                sourceFile = setExcelPrintParameter(sourceFile.getPath());
            }
            //文件转化
            JodConverter.convert(sourceFile).to(newFile).execute();
        }finally {
            // 关闭localOfficeManager服务
            OfficeUtils.stopQuietly(localOfficeManager);
        }
        return outFilePath;
    }

    /**
     * 设置Excel打印参数
     *
     * @param sourceFilePath 源文件路径
     */
    private File setExcelPrintParameter(String sourceFilePath) throws IOException {
        File sourceFile = new File(sourceFilePath);
        Workbook workbook = WorkbookFactory.create(new FileInputStream(sourceFile));
        for (int i = 0; i < workbook.getNumberOfSheets(); i++) {
            Sheet sheet = workbook.getSheetAt(i);
            sheet.setFitToPage(true);
            PrintSetup printSetup = sheet.getPrintSetup();
            printSetup.setFitWidth((short) 1);
            printSetup.setFitHeight((short) 408);
            //设置打印方向，横向就是true
            printSetup.setLandscape(false);
            //设置A4纸
            printSetup.setPaperSize(HSSFPrintSetup.A4_PAPERSIZE);
        }
        workbook.write(new FileOutputStream(sourceFile));
        return sourceFile;
    }


}
